#!/usr/bin/python
# -*- coding:UTF-8 -*-
# @Time    : 2019/1/9 14:10
# @Author  : 王志鹏
# @Site    : 
# @File    : d1.py
# @Software: PyCharm

"""
尽管将一个系统分割成许多对象通常可以增加其可复用性,但是对象间互相链接的激增又会降低其可复用性了
大量的链接使得一个对象不可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,所以,对系统进行比较大的改动就十分困难了

中介者模式 Mediator: 用一个对象来封装一系列对象的交互.中介者使各对象不需要显示的相互引用,从而使其耦合分散,而且可以独立的改变他们之间的互相交互

优缺点 :中介者模式很容易在系统中应用,也很容易在系统中误用.当系统出现了'多对多'交互复杂的对象群时不要急用中介模式,先要反思系统在设计上是不是合理
减少了Colleague中的耦合可以独立的改变和复用Mediator和Colleague
其次由于吧对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个的对象中,这样关注的对象就从对象的本身的行为转移到他们之间的交互上来
也就站在更宏观的角度去看待系统

缺点:
由于ConcreteMediator控制了集中化,于是就把交互的复杂性变为了中介者的复杂性,者就使得中介者会比任何一个ConcreteColleague都要复杂

使用场景:
中介者模式一般应用于一组对象以及定义良好但是复杂的方式进行通信的场合,以及向定制一个分部在多个类中的行为,而又不生成太多子类的场合
"""

import abc


class Mediator(object):
    __metaclass__ = abc.ABCMeta

    def __init__(self):
        self.colleague1 = None
        self.colleague2 = None

    @abc.abstractmethod
    def send(self, message, colleague): pass


# 中介者
class ConcreteMediator(Mediator):
    def send(self, message, colleague):
        if colleague == type(self.colleague1):
            self.colleague2.Notify(message)
        else:
            self.colleague1.Notify(message)


class Colleague(object):
    __metaclass__ = abc.ABCMeta

    def __init__(self, mediator=None):
        self.mediator = mediator  # 中介对象


class ConcreteColleague1(Colleague):
    def send(self, message):
        self.mediator.send(message, ConcreteColleague1)

    def Notify(self, message):
        print "同事1得到信息:%s" % message


class ConcreteColleague2(Colleague):
    def send(self, message):
        self.mediator.send(message, ConcreteColleague2)

    def Notify(self, message):
        print "同事2得到信息:%s" % message


if __name__ == '__main__':
    m = ConcreteMediator()
    c1 = ConcreteColleague1(m)
    c2 = ConcreteColleague2(m)

    m.colleague1 = c1
    m.colleague2 = c2

    c1.send("吃饭了吗?")
    c2.send("没呢!你要请客?")
